package com.concurrent.demo;

import javax.swing.text.DateFormatter;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Vector;
import java.util.concurrent.*;

/**
 * @Date 2020/7/10 13:04
 * @Author admin
 * @Description
 */
public class  AccountCheck <P,D> {
    //订单队列
    Vector<P> pos;
    //派送队列
    Vector<D> dos;
    //执行回调的线程池
    Executor executor = Executors.newFixedThreadPool(1);
    //CyclicBarrier 内置的有一个计数器，计数器为零时会调用传入的回调函数
    final CyclicBarrier barrier =
            new CyclicBarrier(2,()->{
                executor.execute(()->check());
            });
    void check(){
        P p = pos.remove(0);
        D d = dos.remove(0);
        //执行对账操作
        String diff = check(p,d);
        save(diff);
    }
    public String check(P pos, D dos){
        return null;
    }
    public void save(String diff){

    }

    void checkAll(){
        //循环查询订单库
        Thread T1 = new Thread(()->{
            while (true){
                //当存在未对账订单
                //查询订单库
                pos.add((P) getPOrders());
                //等待 会将计数器减1
                try {
                    barrier.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            }
        });
        T1.start();
        //循环查询运单库
        Thread T2 = new Thread(()->{
            while (true){
                //当存在为对账订单时
                //查询运单库
                dos.add((D) getDOrders());
                //等待 会将内置计数器减1
                try {
                    barrier.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            }
        });
        T2.start();
    }

    public void check1(){
        while(haveDealOrder()){//存在未对账订单  循环内部重复创建线程-->>优化：使用线程池
            //查询订单
            Thread t1= new Thread(()->{
                pos = getPOrders();//开启线程 查询未对账订单
            }
            );
            t1.start();
            //查询运单
            Thread t2 = new Thread(()->{
                dos = getDOrders();//开启线程 查询派送单
            });
            t2.start();

            //join让主线程等待t1 t2查询结果执行对账
            try {
                t1.join();//使用join让主线程等待join的线程执行结束开始执行
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            try {
                t2.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //对账
            String diff = check(pos, dos);
            //差异入库
            save(diff);
        }
    }
    public String check(Vector<P> pos, Vector<D> dos){
        return null;
    }
    public Vector<P> getPOrders(){
        return new Vector();
    }
    public Vector<D> getDOrders(){
        return new Vector<D>();
    }

    /**
     * 存在未对账订单
     * @return
     */
    public boolean haveDealOrder(){
        return true;
    }

    //用CountDownLatch实现线程等待
    Executor executor1 = Executors.newFixedThreadPool(2);
    public void countDownLatch(){
        //存在未对账账单时
        while(haveDealOrder()){
            //初始化2的计数器
            CountDownLatch countDownLatch = new CountDownLatch(2);
            //通过线程池执行线程任务--》》查询未对账订单
            executor1.execute(()->{
                pos = getPOrders();
                countDownLatch.countDown();
            });
            //通过线程池执行线程任务--》》查询派送单
            executor1.execute(()->{
                dos = getDOrders();
                countDownLatch.countDown();
            });
            //等待两个查询结果结束
            try {
                countDownLatch.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            String diff = check(pos, dos);
            save(diff);
        }
    }

    public static void main(String[] args) {
        LocalDate date = LocalDate.now();
        String substring = date.toString().substring(5, 7);
        String substring1 = date.toString().substring(8, 10);
        System.out.println(substring);
        System.out.println(substring1);
        System.out.println(date);
    }
}
